package com.joysuch.wwyt.api.sync.service.impl;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.joysuch.wwyt.api.sync.SyncConstants;
import com.joysuch.wwyt.api.sync.SyncJobUtil;
import com.joysuch.wwyt.api.sync.SyncResponse;
import com.joysuch.wwyt.api.sync.bean.BaseSyncUserCertBean;
import com.joysuch.wwyt.api.sync.service.BaseSyncUserCertService;
import com.joysuch.wwyt.bp.entity.contractor.BpContractorStaff;
import com.joysuch.wwyt.bp.enums.DataStateTypes;
import com.joysuch.wwyt.bp.repository.BpContractorStaffDao;
import com.joysuch.wwyt.core.common.ajax.ResultBean;
import com.joysuch.wwyt.core.entity.BaseConfig;
import com.joysuch.wwyt.core.entity.BaseUser;
import com.joysuch.wwyt.core.repository.BaseUserDao;
import com.joysuch.wwyt.core.service.BaseConfigService;
import com.joysuch.wwyt.core.service.BizCodeGeneratorFacade;
import com.joysuch.wwyt.edu.entity.EduCertificate;
import com.joysuch.wwyt.edu.entity.EduCertificateUser;
import com.joysuch.wwyt.edu.enums.CertificateTypes;
import com.joysuch.wwyt.edu.repository.EduCertificateDao;
import com.joysuch.wwyt.edu.repository.EduCertificateUserDao;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import java.util.*;

@Service
@Slf4j
public class BaseSyncUserCertServiceImpl implements BaseSyncUserCertService {

    @Autowired
    private BaseConfigService baseConfigService;

    @Autowired
    private RestTemplate restTemplate;

    @Autowired
    private EduCertificateDao certificateDao;

    @Autowired
    private BaseUserDao baseUserDao;

    @Autowired
    private BpContractorStaffDao contractorStaffDao;

    @Autowired
    private EduCertificateUserDao certificateUserDao;

    @Autowired
    private BizCodeGeneratorFacade bizCodeGeneratorFacade;

    @Override
    public ResultBean syncUserCert(boolean isUser) {
        log.info("人员证书列表同步Job 开始 ...");
        Set<String> bukrs = SyncConstants.unitCodeMap.keySet();
        List<String> msgList = new ArrayList<>();
        for(String companyCode: bukrs){
            try {
                ResultBean result = syncUserCertByCompany(companyCode, isUser);
                msgList.add(result.getData().toString());
            }catch(Exception e){
                log.error("人员证书列表同步出错： companyCode={}",companyCode,e);
            }
        }
        log.info("人员证书列表同步Job 结束 ...");
        return ResultBean.success(msgList);
    }

    @Override
    public ResultBean syncUserCertByCompany(String companyCode, boolean isUser) {
        String url = isUser ? SyncConstants.BASE_CONFIG_USER_CERT_LIST_URL: SyncConstants.BASE_CONFIG_CONTRACTOR_USER_CERT_LIST_URL;
        BaseConfig config = baseConfigService.findConfig(SyncConstants.TENENT_ID_DEFAULT, companyCode, url);
        if (config != null && StringUtils.isNotEmpty(config.getValue())) {
            HttpHeaders header = new HttpHeaders();
            header.setContentType(MediaType.APPLICATION_JSON);
            //set request body
            HttpEntity<String> requestBody = new HttpEntity<String>(companyCode, header);
            log.info("人员证书列表同步Job：url={}, param={}", config.getValue());

            SyncResponse response = restTemplate.postForObject(config.getValue(), requestBody, SyncResponse.class);
            if (response.getMsgcode().equals("0")) {
                if (response.getData() == null) {
                    log.info("人员证书列表同步Job： 获取数据列表为空， URL={}", config.getValue());
                    return ResultBean.success("人员证书列表同步完成：  共同步0条记录；");
                }
                String data = JSONObject.toJSONString(response.getData());

                JSONObject content = JSONObject.parseObject(data);
                Integer count= processList(content.getString("content"), companyCode, isUser);


                return ResultBean.success("人员证书列表同步结束： 共同步" + count.toString() + "条记录；" );
            } else {
                log.error("人员证书列表同步Job： 接口数据获取失败： {}", response);
                return ResultBean.success("人员证书列表同步失败：  接口数据获取失败；");
            }
        }
        return ResultBean.success("人员证书列表同步失败：  同步接口未配置；");
    }

    // 人员证书信息处理
    private Integer processList (String content, String companyCode, boolean isUser){
        if(content == null){
            return 0;
        }
        List<BaseSyncUserCertBean> list = JSONArray.parseArray(content, BaseSyncUserCertBean.class );
        log.info(".... 人员证书同步Job： 共查询列表 list:{} ....", list.size());
        Map<String, Long> certMap = getCertMap(companyCode);

        Long certId;
        Long userId;
        List<EduCertificateUser> certUserList = new ArrayList<>();
        int count = 0;
        for(BaseSyncUserCertBean bean: list){
            if(bean.getOrgCode() == null || !companyCode.equals(bean.getOrgCode())){
                continue;
            }
            if(isUser){
                BaseUser user = baseUserDao.findByCodeAndCompanyCode(bean.getUserid(),bean.getOrgCode());
                if(user == null) {
                    continue;
                }
                userId = user.getId();
            }else{
                BpContractorStaff contractorStaff = contractorStaffDao.findByCodeAndCompanyCode(bean.getUserid(), companyCode);
                if(contractorStaff == null) {
                    continue;
                }
                userId = contractorStaff.getId();
            }

            EduCertificateUser certUser = null;
            if(certMap.containsKey(bean.getName())) {
                certUser = certificateUserDao.findFirstByCertNo(bean.getCode());
            }else {
                certId = createNewCert(bean.getName(), companyCode);
                certMap.put(bean.getName(), certId);
            }
            if(certUser == null) {
                certUser = new EduCertificateUser();
                certUser.setCertNo(bean.getCode().trim());
                certUser.setOutOfDateTime(bean.getCertExpireTime());
                certUser.setTakenTime(bean.getCertStartTime());
                certUser.setUserId(userId);
                certUser.setCertId(certMap.get(bean.getName()));
                certUser.setOrgCode(companyCode);
                certUser.setUserContractorFlag(isUser ? 0: 1);
                certUser.setTenentId(SyncConstants.TENENT_ID_DEFAULT);
                certUser.setDeleteFlag("0");
                certUser.setRefUrl(bean.getRefUrl());
                certUser.setCertificateStatus(1);

                certUserList.add(certUser);
                count ++;
            }else{
                if(SyncJobUtil.checkIfDifferent(certUser.getOutOfDateTime(), bean.getCertExpireTime())
                   || SyncJobUtil.checkIfDifferent(certUser.getTakenTime(), bean.getCertStartTime())
                   || SyncJobUtil.checkIfDifferent(certUser.getCertId(),certMap.get(bean.getName()))
                   || SyncJobUtil.checkIfDifferent(certUser.getRefUrl(), bean.getRefUrl())) {
                    certUser.setOutOfDateTime(bean.getCertExpireTime());
                    certUser.setTakenTime(bean.getCertStartTime());
                    certUser.setCertId(certMap.get(bean.getName()));
                    certUser.setRefUrl(bean.getRefUrl());
                    certUser.setCertificateStatus(1);
                    certUserList.add(certUser);
                    count ++;
                }
            }

            //批量更新， 每100 个更新一批
            if(certUserList.size() >=100){
                certificateUserDao.saveAll(certUserList);
                log.info(".... 人员证书同步Job： 已同步人员证书列表 list:{} ....", certUserList.size());
                certUserList = new ArrayList<>();
            }
        }

        if(certUserList.size() >0){
            certificateUserDao.saveAll(certUserList);
            log.info(".... 人员证书同步Job： 已同步人员证书列表 list:{} ....", certUserList.size());
        }

        return count;
    }


    private Map<String, Long> getCertMap(String companyCode) {
        List<EduCertificate> list = certificateDao.findByCompany(
                companyCode, SyncConstants.TENENT_ID_DEFAULT);
        Map<String, Long> map = new HashMap<>();
        for(EduCertificate c: list){
            map.put(c.getName(), c.getId());
        }
        return map;
    }

    private Long createNewCert(String name, String orgCode) {
        EduCertificate cert  = new EduCertificate();
        cert.setName(name);
        cert.setDeleteFlag("0");
        cert.setOrgCode(orgCode);

        cert.setTenentId(SyncConstants.TENENT_ID_DEFAULT);
        cert.setState((byte) 0);
        cert.setExpireRemindOrNot(0);
        cert.setCode(bizCodeGeneratorFacade.zhengShu());
        cert.setEffectiveType(CertificateTypes.LIMITED_MONTHS.getCode());
        cert = certificateDao.save(cert);
        return cert.getId();

    }
}
